package com.example.fwx;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.Priority;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.qweather.sdk.bean.geo.GeoBean;
import com.qweather.sdk.bean.weather.WeatherDailyBean;
import com.qweather.sdk.view.HeConfig;
import com.qweather.sdk.view.QWeather;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

public class Weather extends Fragment {
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
    private static final String TAG = "WeatherFragment";
    private FusedLocationProviderClient fusedLocationClient;
    private LocationCallback locationCallback;

    EditText etcity;
    static TextView tvcity;
    static TextView tvtq1, tvtq2, tvtq3;
    static TextView tvwd1, tvwd2, tvwd3;
    static TextView tvsd1, tvsd2, tvsd3;
    static TextView tvhd1, tvhd2, tvhd3;
    TextView tvrq1, tvrq2, tvrq3;
    Button btnquery, btnlocation;
    String strcityname, strcityid, strcs;
    String strrq1, strrq2, strrq3;
    String strwd1, strwd2, strwd3;
    String strsd1, strsd2, strsd3;
    String strtq1, strtq2, strtq3;
    String strhd1, strhd2, strhd3;
    MyHandler mHandler;

    // 接收从线程中传回来的天气信息
    private class MyHandler extends Handler {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                tvcity.setText("所在城市：" + msg.getData().getString("cs"));
                tvrq1.setText("预报日期：" + msg.getData().getString("rq1"));
                tvtq1.setText("预报天气：" + msg.getData().getString("tq1"));
                tvwd1.setText("最高温度：" + msg.getData().getString("wd1"));
                tvsd1.setText("最低温度：" + msg.getData().getString("sd1"));
                tvhd1.setText("相对湿度：" + msg.getData().getString("hd1"));

                tvrq2.setText("预报日期：" + msg.getData().getString("rq2"));
                tvtq2.setText("预报天气：" + msg.getData().getString("tq2"));
                tvwd2.setText("最高温度：" + msg.getData().getString("wd2"));
                tvsd2.setText("最低温度：" + msg.getData().getString("sd2"));
                tvhd2.setText("相对湿度：" + msg.getData().getString("hd2"));

                tvrq3.setText("预报日期：" + msg.getData().getString("rq3"));
                tvtq3.setText("预报天气：" + msg.getData().getString("tq3"));
                tvwd3.setText("最高温度：" + msg.getData().getString("wd3"));
                tvsd3.setText("最低温度：" + msg.getData().getString("sd3"));
                tvhd3.setText("相对湿度：" + msg.getData().getString("hd3"));
            }
        }
    }

    @SuppressLint("MissingInflatedId")
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_weather, container, false);

        // 初始化FusedLocationProviderClient
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity());

        // 初始化位置回调
        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if (locationResult == null) {
                    showToastOnUiThread("位置更新失败");
                    return;
                }

                List<Location> locations = locationResult.getLocations();
                if (locations.isEmpty()) {
                    showToastOnUiThread("未获取到位置信息");
                    return;
                }

                Location location = locations.get(0);
                // 使用Geocoder先尝试转换位置为地址
                String cityName = getCityNameFromLocation(location);
                if (cityName != null) {
                    // 如果能获取到城市名，直接查询天气
                    getWeatherByCity(cityName);
                } else {
                    // 否则使用坐标查询
                    queryWeatherByLocation(location.getLatitude(), location.getLongitude());
                }
            }
        };

        etcity = rootView.findViewById(R.id.et_city);
        tvcity = rootView.findViewById(R.id.tv_city);
        tvrq1 = rootView.findViewById(R.id.tv_rq);
        tvtq1 = rootView.findViewById(R.id.tv_tq);
        tvwd1 = rootView.findViewById(R.id.tv_wd);
        tvsd1 = rootView.findViewById(R.id.tv_sd);
        tvhd1 = rootView.findViewById(R.id.tv_hd);

        tvrq2 = rootView.findViewById(R.id.tv_rq2);
        tvtq2 = rootView.findViewById(R.id.tv_tq2);
        tvwd2 = rootView.findViewById(R.id.tv_wd2);
        tvsd2 = rootView.findViewById(R.id.tv_sd2);
        tvhd2 = rootView.findViewById(R.id.tv_hd2);

        tvrq3 = rootView.findViewById(R.id.tv_rq3);
        tvtq3 = rootView.findViewById(R.id.tv_tq3);
        tvwd3 = rootView.findViewById(R.id.tv_wd3);
        tvsd3 = rootView.findViewById(R.id.tv_sd3);
        tvhd3 = rootView.findViewById(R.id.tv_hd3);

        btnquery = rootView.findViewById(R.id.btn_query);
        btnlocation = rootView.findViewById(R.id.btn_location);

        mHandler = new MyHandler();
        // 免费秘钥
        HeConfig.init("HE2406071754361703", "c1331c7a51784d7b8bded41a2df0f4ef");
        // 切换到中国区域服务
        HeConfig.switchToDevService();

        // 定位按钮点击事件
        btnlocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkLocationPermission();
            }
        });

        btnquery.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                strcityname = etcity.getText().toString().trim();
                if (strcityname.isEmpty()) {
                    showToastOnUiThread("请输入城市名称");
                    return;
                }

                getWeatherByCity(strcityname);
            }
        });
        return rootView;
    }

    // 使用城市名直接获取天气
    private void getWeatherByCity(String cityName) {
        Log.d(TAG, "按城市名查询天气: " + cityName);

        // 新建线程获取天气服务器的天气信息
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 查询输入城市的城市名称和ID号
                QWeather.getGeoCityLookup(getContext(), cityName, new QWeather.OnResultGeoListener() {
                    @Override
                    public void onError(Throwable throwable) {
                        Log.e(TAG, "查询城市失败: " + cityName, throwable);
                        showToastOnUiThread("查询失败，请检查城市名称是否正确");
                    }

                    @Override
                    public void onSuccess(GeoBean geoBean) {
                        List<GeoBean.LocationBean> locationBeans = geoBean.getLocationBean();
                        if (locationBeans != null && !locationBeans.isEmpty()) {
                            strcs = locationBeans.get(0).getName();
                            strcityid = locationBeans.get(0).getId();
                            Log.d(TAG, "城市查询成功: " + strcs + ", ID: " + strcityid);

                            // 查询输入城市预报天气的预报日期,天气,气温和湿度
                            QWeather.getWeather3D(getContext(), strcityid, new QWeather.OnResultWeatherDailyListener() {
                                @Override
                                public void onError(Throwable throwable) {
                                    Log.e(TAG, "获取天气信息失败", throwable);
                                    showToastOnUiThread("获取天气信息失败");
                                }

                                @Override
                                public void onSuccess(WeatherDailyBean weatherDailyBean) {
                                    List<WeatherDailyBean.DailyBean> db = weatherDailyBean.getDaily();
                                    strrq1 = db.get(0).getFxDate();
                                    strtq1 = db.get(0).getTextDay();
                                    strwd1 = db.get(0).getTempMax();
                                    strsd1 = db.get(0).getTempMin();
                                    strhd1 = db.get(0).getHumidity();

                                    strrq2 = db.get(1).getFxDate();
                                    strtq2 = db.get(1).getTextDay();
                                    strwd2 = db.get(1).getTempMax();
                                    strsd2 = db.get(1).getTempMin();
                                    strhd2 = db.get(1).getHumidity();

                                    strrq3 = db.get(2).getFxDate();
                                    strtq3 = db.get(2).getTextDay();
                                    strwd3 = db.get(2).getTempMax();
                                    strsd3 = db.get(2).getTempMin();
                                    strhd3 = db.get(2).getHumidity();

                                    // 向主线程（UI线程）发送天气信息
                                    if (strcs != null && strtq1 != null) {
                                        Message message = Message.obtain();
                                        message.what = 1;
                                        Bundle bundle = new Bundle();
                                        bundle.putString("cs", strcs);
                                        bundle.putString("rq1", strrq1);
                                        bundle.putString("tq1", strtq1);
                                        bundle.putString("wd1", strwd1);
                                        bundle.putString("sd1", strsd1);
                                        bundle.putString("hd1", strhd1);

                                        bundle.putString("rq2", strrq2);
                                        bundle.putString("tq2", strtq2);
                                        bundle.putString("wd2", strwd2);
                                        bundle.putString("sd2", strsd2);
                                        bundle.putString("hd2", strhd2);

                                        bundle.putString("rq3", strrq3);
                                        bundle.putString("tq3", strtq3);
                                        bundle.putString("wd3", strwd3);
                                        bundle.putString("sd3", strsd3);
                                        bundle.putString("hd3", strhd3);
                                        message.setData(bundle);
                                        mHandler.sendMessage(message);
                                        // 清空临时变量
                                        clearTempVariables();
                                    }
                                }
                            });
                        } else {
                            Log.e(TAG, "未找到城市: " + cityName);
                            showToastOnUiThread("未找到该城市");
                        }
                    }
                });
            }
        }).start();
    }

    // 清空临时变量
    private void clearTempVariables() {
        strcs = null;
        strrq1 = null; strtq1 = null; strwd1 = null; strsd1 = null; strhd1 = null;
        strrq2 = null; strtq2 = null; strwd2 = null; strsd2 = null; strhd2 = null;
        strrq3 = null; strtq3 = null; strwd3 = null; strsd3 = null; strhd3 = null;
        strcityname = null;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        // 移除位置更新，避免内存泄漏
        try {
            if (fusedLocationClient != null && locationCallback != null) {
                fusedLocationClient.removeLocationUpdates(locationCallback);
            }
        } catch (Exception e) {
            Log.e(TAG, "移除位置更新失败", e);
        }
    }

    // 从经纬度获取城市名称
    private String getCityNameFromLocation(Location location) {
        try {
            Geocoder geocoder = new Geocoder(requireContext(), Locale.CHINA);
            List<Address> addresses = geocoder.getFromLocation(
                    location.getLatitude(), location.getLongitude(), 1);

            if (addresses != null && !addresses.isEmpty()) {
                Address address = addresses.get(0);

                // 从地址信息中获取城市名，优先使用城市，如果没有则尝试获取子地区或地区
                String cityName = address.getLocality();
                if (cityName == null) {
                    cityName = address.getSubAdminArea();
                }
                if (cityName == null) {
                    cityName = address.getAdminArea();
                }

                Log.d(TAG, "通过Geocoder获取到城市名: " + cityName);
                return cityName;
            }
        } catch (IOException e) {
            Log.e(TAG, "Geocoder获取地址失败", e);
        } catch (Exception e) {
            Log.e(TAG, "获取城市名称时出现异常", e);
        }
        return null;
    }

    // 检查位置权限
    private void checkLocationPermission() {
        if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // 请求权限
            ActivityCompat.requestPermissions(requireActivity(),
                    new String[]{
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                    },
                    LOCATION_PERMISSION_REQUEST_CODE);
        } else {
            // 已有权限，获取位置
            getCurrentLocation();
        }
    }

    // 处理权限请求结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            boolean allGranted = true;
            for (int result : grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allGranted = false;
                    break;
                }
            }

            if (allGranted) {
                getCurrentLocation();
            } else {
                Toast.makeText(getContext(), "需要位置权限才能获取当前位置", Toast.LENGTH_SHORT).show();
            }
        }
    }

    // 获取当前位置
    @SuppressLint("MissingPermission")
    private void getCurrentLocation() {
        Toast.makeText(getContext(), "正在获取位置...", Toast.LENGTH_SHORT).show();
        tvcity.setText("正在获取位置...");

        // 检查位置服务是否开启
        LocationManager locationManager = (LocationManager) requireActivity().getSystemService(Context.LOCATION_SERVICE);
        boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGpsEnabled && !isNetworkEnabled) {
            Toast.makeText(getContext(), "请在系统设置中开启位置服务", Toast.LENGTH_LONG).show();
            tvcity.setText("请开启位置服务");

            // 打开位置设置界面
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
            return;
        }

        // 首先尝试获取最后已知位置
        fusedLocationClient.getLastLocation()
                .addOnSuccessListener(requireActivity(), new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        if (location != null) {
                            Log.d(TAG, "获取到最后已知位置: " + location.getLatitude() + ", " + location.getLongitude());

                            // 使用Geocoder先尝试转换位置为地址
                            String cityName = getCityNameFromLocation(location);
                            if (cityName != null) {
                                // 如果能获取到城市名，直接查询天气
                                getWeatherByCity(cityName);
                            } else {
                                // 否则使用坐标查询
                                queryWeatherByLocation(location.getLatitude(), location.getLongitude());
                            }
                        } else {
                            Log.d(TAG, "最后已知位置为null，尝试请求新位置");
                            // 如果获取不到最后已知位置，则请求新位置
                            requestNewLocation();
                        }
                    }
                })
                .addOnFailureListener(requireActivity(), new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Log.e(TAG, "获取最后已知位置失败", e);
                        showToastOnUiThread("获取位置失败: " + e.getMessage());
                        // 尝试请求新位置
                        requestNewLocation();
                    }
                });
    }

    // 请求新位置更新
    @SuppressLint("MissingPermission")
    private void requestNewLocation() {
        try {
            Log.d(TAG, "请求位置更新");
            showToastOnUiThread("正在请求位置更新...");

            LocationRequest locationRequest = new LocationRequest.Builder(10000)
                    .setPriority(Priority.PRIORITY_HIGH_ACCURACY)
                    .setWaitForAccurateLocation(false)
                    .setMinUpdateIntervalMillis(5000)
                    .setMaxUpdateDelayMillis(20000)
                    .setMaxUpdates(1)
                    .build();

            fusedLocationClient.requestLocationUpdates(locationRequest,
                            locationCallback, Looper.getMainLooper())
                    .addOnFailureListener(e -> {
                        Log.e(TAG, "请求位置更新失败", e);
                        showToastOnUiThread("请求位置更新失败: " + e.getMessage());
                    })
                    .addOnSuccessListener(aVoid -> {
                        Log.d(TAG, "已开始请求位置更新");
                    });

        } catch (Exception e) {
            Log.e(TAG, "请求位置更新出错", e);
            showToastOnUiThread("请求位置更新出错: " + e.getMessage());
            tvcity.setText("定位失败，请重试");
        }
    }

    // 根据经纬度查询天气
    private void queryWeatherByLocation(double latitude, double longitude) {
        Log.d(TAG, "根据位置查询天气: " + latitude + ", " + longitude);
        // 显示正在查询中的提示
        tvcity.setText("正在查询当前位置的天气...");

        // 检查坐标是否在合理范围内
        if (latitude < -90 || latitude > 90 || longitude < -180 || longitude > 180) {
            Log.e(TAG, "无效的坐标值: latitude=" + latitude + ", longitude=" + longitude);
            showToastOnUiThread("获取到的位置坐标无效，请重试");
            tvcity.post(() -> tvcity.setText("位置坐标无效，请重试"));
            return;
        }

        // 格式化坐标 - 使用和风天气要求的格式：经度,纬度
        String locationParam = String.format(Locale.US, "%.6f,%.6f", longitude, latitude);
        Log.d(TAG, "使用坐标参数: " + locationParam);

        // 新建线程获取天气
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 使用和风天气SDK的坐标查询API获取位置信息
                    QWeather.getGeoCityLookup(getContext(), locationParam, new QWeather.OnResultGeoListener() {
                        @Override
                        public void onError(Throwable throwable) {
                            Log.e(TAG, "位置查询失败", throwable);
                            Log.e(TAG, "位置查询失败详情: " + throwable.getMessage());
                            showToastOnUiThread("位置查询失败");
                        }

                        @Override
                        public void onSuccess(GeoBean geoBean) {
                            List<GeoBean.LocationBean> locationBeans = geoBean.getLocationBean();
                            if (locationBeans != null && !locationBeans.isEmpty()) {
                                strcs = locationBeans.get(0).getName();
                                strcityid = locationBeans.get(0).getId();
                                Log.d(TAG, "位置查询成功: " + strcs + ", ID: " + strcityid);

                                // 查询该位置的天气预报
                                QWeather.getWeather3D(getContext(), strcityid, new QWeather.OnResultWeatherDailyListener() {
                                    @Override
                                    public void onError(Throwable throwable) {
                                        Log.e(TAG, "天气查询失败", throwable);
                                        showToastOnUiThread("天气查询失败，请重试");
                                        tvcity.post(() -> tvcity.setText("天气查询失败，请重试"));
                                    }

                                    @Override
                                    public void onSuccess(WeatherDailyBean weatherDailyBean) {
                                        List<WeatherDailyBean.DailyBean> db = weatherDailyBean.getDaily();
                                        strrq1 = db.get(0).getFxDate();
                                        strtq1 = db.get(0).getTextDay();
                                        strwd1 = db.get(0).getTempMax();
                                        strsd1 = db.get(0).getTempMin();
                                        strhd1 = db.get(0).getHumidity();

                                        strrq2 = db.get(1).getFxDate();
                                        strtq2 = db.get(1).getTextDay();
                                        strwd2 = db.get(1).getTempMax();
                                        strsd2 = db.get(1).getTempMin();
                                        strhd2 = db.get(1).getHumidity();

                                        strrq3 = db.get(2).getFxDate();
                                        strtq3 = db.get(2).getTextDay();
                                        strwd3 = db.get(2).getTempMax();
                                        strsd3 = db.get(2).getTempMin();
                                        strhd3 = db.get(2).getHumidity();

                                        Log.d(TAG, "天气查询成功");
                                        // 向主线程发送天气信息
                                        if (strcs != null && strtq1 != null) {
                                            Message message = Message.obtain();
                                            message.what = 1;
                                            Bundle bundle = new Bundle();
                                            bundle.putString("cs", strcs);
                                            bundle.putString("rq1", strrq1);
                                            bundle.putString("tq1", strtq1);
                                            bundle.putString("wd1", strwd1);
                                            bundle.putString("sd1", strsd1);
                                            bundle.putString("hd1", strhd1);

                                            bundle.putString("rq2", strrq2);
                                            bundle.putString("tq2", strtq2);
                                            bundle.putString("wd2", strwd2);
                                            bundle.putString("sd2", strsd2);
                                            bundle.putString("hd2", strhd2);

                                            bundle.putString("rq3", strrq3);
                                            bundle.putString("tq3", strtq3);
                                            bundle.putString("wd3", strwd3);
                                            bundle.putString("sd3", strsd3);
                                            bundle.putString("hd3", strhd3);

                                            message.setData(bundle);
                                            mHandler.sendMessage(message);
                                            // 清空临时变量
                                            clearTempVariables();
                                        }
                                    }
                                });
                            } else {
                                Log.e(TAG, "未找到位置信息");
                                showToastOnUiThread("未找到位置信息");
                                tvcity.post(() -> tvcity.setText("未找到位置信息"));
                            }
                        }
                    });
                } catch (Exception e) {
                    Log.e(TAG, "坐标位置查询出现异常", e);
                    showToastOnUiThread("位置查询出错");
                }
            }
        }).start();
    }

    // 在UI线程中显示Toast消息
    private void showToastOnUiThread(final String message) {
        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}